#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
主窗口UI实现
"""

import os
from PyQt5.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, 
                            QPushButton, QLabel, QFileDialog, QComboBox,
                            QSpinBox, QGroupBox, QFormLayout, QMessageBox,
                            QProgressBar, QSplitter, QScrollArea)
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtCore import Qt, QSize

from src.converter.binary_converter import BinaryConverter
from src.utils.file_utils import get_file_size_str

class MainWindow(QMainWindow):
    """
    应用程序主窗口类
    """
    def __init__(self):
        super().__init__()
        
        # 设置窗口标题和大小
        self.setWindowTitle("二进制文件转图片工具")
        self.resize(900, 600)
        
        # 初始化UI组件
        self.init_ui()
        
        # 初始化转换器
        self.converter = BinaryConverter()
        
        # 初始化变量
        self.binary_file_path = ""
        self.output_image_path = ""
        self.current_image = None

    def init_ui(self):
        """
        初始化UI组件
        """
        # 创建中央部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        # 创建主布局
        main_layout = QVBoxLayout(central_widget)
        
        # 创建分割器，用于分隔控制面板和图片预览
        splitter = QSplitter(Qt.Horizontal)
        main_layout.addWidget(splitter)
        
        # 创建左侧控制面板
        control_panel = QWidget()
        control_layout = QVBoxLayout(control_panel)
        splitter.addWidget(control_panel)
        
        # 文件选择组
        file_group = QGroupBox("文件选择")
        file_layout = QVBoxLayout()
        
        # 选择二进制文件
        self.file_path_label = QLabel("未选择文件")
        self.file_size_label = QLabel("文件大小: 0 KB")
        
        select_file_btn = QPushButton("选择二进制文件")
        select_file_btn.clicked.connect(self.select_binary_file)
        
        file_layout.addWidget(select_file_btn)
        file_layout.addWidget(self.file_path_label)
        file_layout.addWidget(self.file_size_label)
        file_group.setLayout(file_layout)
        control_layout.addWidget(file_group)
        
        # 转换选项组
        conversion_group = QGroupBox("转换选项")
        conversion_layout = QFormLayout()
        
        # 图片格式选择
        self.format_combo = QComboBox()
        self.format_combo.addItems(["PNG", "JPEG", "BMP", "TIFF", "GIF"])
        conversion_layout.addRow("输出格式:", self.format_combo)
        
        # 宽度设置
        self.width_spin = QSpinBox()
        self.width_spin.setRange(1, 10000)
        self.width_spin.setValue(512)
        conversion_layout.addRow("图片宽度:", self.width_spin)
        
        # 高度设置（自动计算）
        self.height_label = QLabel("自动计算")
        conversion_layout.addRow("图片高度:", self.height_label)
        
        # 字节解析方式
        self.byte_mode_combo = QComboBox()
        self.byte_mode_combo.addItems(["灰度 (1字节/像素)", "RGB (3字节/像素)", "RGBA (4字节/像素)"])
        self.byte_mode_combo.currentIndexChanged.connect(self.update_height_estimate)
        conversion_layout.addRow("字节解析方式:", self.byte_mode_combo)
        
        conversion_group.setLayout(conversion_layout)
        control_layout.addWidget(conversion_group)
        
        # 转换按钮
        convert_btn = QPushButton("转换")
        convert_btn.clicked.connect(self.convert_file)
        control_layout.addWidget(convert_btn)
        
        # 保存按钮
        save_btn = QPushButton("保存图片")
        save_btn.clicked.connect(self.save_image)
        control_layout.addWidget(save_btn)
        
        # 进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setVisible(False)
        control_layout.addWidget(self.progress_bar)
        
        # 添加弹性空间
        control_layout.addStretch()
        
        # 创建右侧图片预览区域
        preview_container = QWidget()
        preview_layout = QVBoxLayout(preview_container)
        splitter.addWidget(preview_container)
        
        # 图片预览标签
        preview_label = QLabel("图片预览")
        preview_layout.addWidget(preview_label)
        
        # 创建滚动区域用于图片预览
        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        preview_layout.addWidget(scroll_area)
        
        # 图片显示标签
        self.image_label = QLabel("转换后的图片将显示在这里")
        self.image_label.setAlignment(Qt.AlignCenter)
        self.image_label.setMinimumSize(400, 400)
        scroll_area.setWidget(self.image_label)
        
        # 设置分割器的初始大小
        splitter.setSizes([300, 600])
    
    def select_binary_file(self):
        """
        选择二进制文件
        """
        file_path, _ = QFileDialog.getOpenFileName(
            self, "选择二进制文件", "", "所有文件 (*.*)"
        )
        
        if file_path:
            self.binary_file_path = file_path
            self.file_path_label.setText(os.path.basename(file_path))
            
            # 显示文件大小
            file_size = os.path.getsize(file_path)
            self.file_size_label.setText(f"文件大小: {get_file_size_str(file_size)}")
            
            # 更新高度估计
            self.update_height_estimate()
    
    def update_height_estimate(self):
        """
        根据文件大小和宽度更新高度估计
        """
        if not self.binary_file_path:
            self.height_label.setText("自动计算")
            return
        
        file_size = os.path.getsize(self.binary_file_path)
        width = self.width_spin.value()
        
        # 根据字节模式确定每像素字节数
        bytes_per_pixel = 1  # 默认灰度模式
        mode_idx = self.byte_mode_combo.currentIndex()
        if mode_idx == 1:  # RGB
            bytes_per_pixel = 3
        elif mode_idx == 2:  # RGBA
            bytes_per_pixel = 4
        
        # 计算高度
        if width > 0 and bytes_per_pixel > 0:
            height = file_size / (width * bytes_per_pixel)
            self.height_label.setText(f"≈ {int(height)} 像素")
        else:
            self.height_label.setText("计算错误")
    
    def convert_file(self):
        """
        转换二进制文件为图片
        """
        if not self.binary_file_path:
            QMessageBox.warning(self, "警告", "请先选择二进制文件")
            return
        
        # 获取转换参数
        width = self.width_spin.value()
        format_str = self.format_combo.currentText().lower()
        
        # 获取字节模式
        mode_idx = self.byte_mode_combo.currentIndex()
        if mode_idx == 0:
            mode = "L"  # 灰度
        elif mode_idx == 1:
            mode = "RGB"
        else:
            mode = "RGBA"
        
        try:
            # 显示进度条
            self.progress_bar.setVisible(True)
            self.progress_bar.setValue(0)
            
            # 执行转换
            self.current_image = self.converter.convert_to_image(
                self.binary_file_path, width, mode
            )
            
            # 更新进度条
            self.progress_bar.setValue(100)
            
            # 显示图片
            self.display_image(self.current_image)
            
            QMessageBox.information(self, "成功", "文件转换成功！")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"转换失败: {str(e)}")
        finally:
            # 隐藏进度条
            self.progress_bar.setVisible(False)
    
    def display_image(self, image):
        """
        在界面上显示图片
        """
        if image:
            # 将PIL图像转换为QImage
            if image.mode == "RGB":
                q_image = QImage(image.tobytes(), image.width, image.height, 
                                image.width * 3, QImage.Format_RGB888)
            elif image.mode == "RGBA":
                q_image = QImage(image.tobytes(), image.width, image.height,
                                image.width * 4, QImage.Format_RGBA8888)
            else:  # 灰度
                q_image = QImage(image.tobytes(), image.width, image.height,
                                image.width, QImage.Format_Grayscale8)
            
            # 创建QPixmap并显示
            pixmap = QPixmap.fromImage(q_image)
            self.image_label.setPixmap(pixmap)
            self.image_label.setMinimumSize(pixmap.size())
        else:
            self.image_label.setText("无法显示图片")
    
    def save_image(self):
        """
        保存转换后的图片
        """
        if not self.current_image:
            QMessageBox.warning(self, "警告", "没有可保存的图片")
            return
        
        # 获取格式
        format_str = self.format_combo.currentText().lower()
        
        # 打开保存对话框
        file_path, _ = QFileDialog.getSaveFileName(
            self, "保存图片", "", f"{format_str.upper()} 文件 (*.{format_str})"
        )
        
        if file_path:
            try:
                # 确保文件有正确的扩展名
                if not file_path.lower().endswith(f".{format_str}"):
                    file_path += f".{format_str}"
                
                # 保存图片
                self.current_image.save(file_path, format=format_str.upper())
                self.output_image_path = file_path
                
                QMessageBox.information(self, "成功", f"图片已保存至: {file_path}")
            except Exception as e:
                QMessageBox.critical(self, "错误", f"保存失败: {str(e)}")
